`timescale 1ns / 1ps
`include "defines2.vh"
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2017/10/23 15:21:30
// Design Name: 
// Module Name: maindec
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module maindec(
	input wire[5:0] op,
	input wire[5:0] funct,
	input wire[4:0] rt,

	output wire mfhi,mflo, //yyx
	output hi_write,lo_write,//yyx
	output [1:0] hi_mdr,lo_mdr,

	output wire memtoreg,memwrite,
	output wire branch,alusrc,
	output wire regdst,regwrite,
	output wire jump,
	output wire jal,jr,bal, //新加的三个与分支指令相关的信号
	
	output wire [1:0] memsize,//新加的关于字11、半字10、字节01的控制信号
	output wire memsignd //新加的关于从内存读取的数有符号扩展(1)或无符号扩展(0)

    );
	
	wire mul, div;
	wire mthi, mtlo;
	
	assign mul = op == `NOP & (funct == `MULT | funct == `MULTU);
	assign div = op == `NOP & (funct == `DIV | funct == `DIVU);
	assign mthi = op == `NOP & funct == `MTHI;
	assign mtlo = op == `NOP & funct == `MTLO;
	
	
	assign hi_mdr = {mul, div, mthi} == 3'b100 ? 2'b01 :
               		{mul, div, mthi} == 3'b010 ? 2'b10 :
               		{mul, div, mthi} == 3'b001 ? 2'b11 :
               		2'b00;
	assign lo_mdr = {mul, div, mthi} == 3'b100 ? 2'b01 :
               		{mul, div, mthi} == 3'b010 ? 2'b10 :
               		{mul, div, mthi} == 3'b001 ? 2'b11 :
               		2'b00;

	assign hi_write = mul | div | mthi;
	assign lo_write = mul | div | mtlo;
	
	
	
	
	reg[16:0] controls;
	assign {regwrite,regdst,alusrc,branch,memwrite,memtoreg,jump,jal,jr,bal,memsize,memsignd,mfhi,mflo,hi_write,lo_write} = controls;
	always @(*) begin
		case (op)
			//访存指令
			`LB:controls <= 17'b1010010_000_011_0000;//Load
			`LBU:controls <= 17'b1010010_000_010_0000;
			`LH:controls <= 17'b1010010_000_101_0000;
			`LHU:controls <= 17'b1010010_000_100_0000;
			`LW:controls <= 17'b1010010_000_111_0000;
			`SB:controls <= 17'b0010100_000_010_0000;//Store
			`SH:controls <= 17'b0010100_000_100_0000;
			`SW:controls <= 17'b0010100_000_110_0000;

			//逻辑指令
			`AND:controls <=17'b1000000_000_000_0000;
			`OR:controls <=17'b1000000_000_000_0000;
			`XOR:controls <=17'b1000000_000_000_0000;
			`NOR:controls <=17'b1000000_000_000_0000;
			`ANDI:controls <=17'b1010000_000_000_0000;
			`ORI:controls <=17'b1010000_000_000_0000;
			`XORI:controls <=17'b1010000_000_000_0000;
			`LUI:controls <=17'b1010000_000_000_0000;

			//算数指令
			`ADDI: controls <= 17'b1010000_000_000_0000;
			`ADDIU: controls <= 17'b1010000_000_000_0000;
			`SLTI: controls <= 17'b1010000_000_000_0000;
			`SLTIU: controls <= 17'b1010000_000_000_0000;

			//跳转指令
			6'b000000:case(funct)
				`JR:controls <= 17'b0000001_010_000_0000;	
				`JALR:controls <= 17'b0000000_110_000_0000;
				//hilo
				`MFHI: controls <= 17'b1100000_000_000_1000;
				`MFLO: controls <= 17'b1100000_000_000_0100; 
				`MTHI: controls <= 17'b0000000_000_000_0010; 
				`MTLO: controls <= 17'b0000000_000_000_0001; 
				//乘除法
				`MULT:controls <= 17'b0100000_000_000_0011;
				`MULTU:controls <= 17'b0100000_000_000_0011;
				`DIV:controls <= 17'b0100000_000_000_0011;
				`DIVU:controls <= 17'b0100000_000_000_0011;

				default:controls <= 17'b1100000_000_000_0000;//R-TYRE
			endcase
			`J:controls <= 17'b0000001_000_000_0000;
			`JAL:controls <= 17'b0000000_100_000_0000;
			`BEQ:controls <= 17'b0001000_000_000_0000;
			`BNE:controls <= 17'b0001000_000_000_0000;
			`BGTZ:controls <= 17'b0001000_000_000_0000;
			`BLEZ:controls <= 17'b0001000_000_000_0000;
			6'b000001:case(rt)
				`BGEZ:controls <= 17'b0001000_000_000_0000;
				`BGEZAL:controls <= 17'b0001000_001_000_0000;
				`BLTZ:controls <= 17'b0001000_000_000_0000;
				`BLTZAL:controls <= 17'b0001000_001_000_0000;
			endcase	
			
			default:  controls <= 17'b0000000_000_000_0000;//illegal op
		
		endcase
	end
endmodule
